#include "Arduino.h"
#include "WiFi.h"
#include <WiFiManager.h>
#include <time.h>
#include <Adafruit_GFX.h>
//#include <Fonts/FreeSans24pt7b.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <U8g2_for_Adafruit_GFX.h>
#include "img.h"
// #include "wea_qing.h"
// #include "wea_duoyun.h"
// #include "wea_xue.h"
// #include "wea_yin.h"
// #include "wea_yu.h"
// #include "da10.jpg.h"
// #include "da11.jpg.h"
// #include "da12.jpg.h"

//全部图标字库:
//https://www.jerrycoding.com/tool/u8g2lib/
//u8g2_font_open_iconic_all_4x_t
//天气图标字库:
//u8g2_font_open_iconic_weather_4x_t
//箭头字库：
//u8x8_font_open_iconic_arrow_4x4


#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"




#define COLOR_GRAY 0x7BEF
#define dotx 120

const char* ssid1 = "comicyu_2f";
const char* password1 = "67799706100";

const char* ssid = "ChinaNet-yu";
const char* password = "ydd200706";

U8G2_FOR_ADAFRUIT_GFX u8g2;
U8G2_FOR_ADAFRUIT_GFX u8g2_2;
U8G2_FOR_ADAFRUIT_GFX u8g2_3;

//const char* ssid = "EspWebServerSetupAP";
//const char* password = "";

//WiFiManager wm;

const image* digitArr[10] = {&da0,&da1,&da2,&da3,&da4,&da5,&da6,&da7,&da8,&da9};//,&da10,&da11,&da12};
String Weather_desc="";
String Weather_temp="";
String Weather_wind="";
String Weather_date="";
String Weather_temp_day="";
String Weather_temp_night="";
String Weather_reportdate="";
String  Weather_desc_day;
String  Weather_desc_night;

int icount=0;
struct tm timeinfo_last;

// int interrupt_counter=0;
// void IRAM_ATTR onTimer()
// {
//   interrupt_counter=1-interrupt_counter;
//   Serial.println("Timer interrupt.");
//   if(interrupt_counter==0)
//   {
//     u8g2_2.setCursor(dotx,120);
//     u8g2_2.print("■");
//     u8g2_2.setCursor(dotx,60);
//     u8g2_2.print("■");
//   }
//   else
//   {
//     tft2.fillRect(dotx,50,20,100,ST77XX_BLACK);
//   }
// }

void drawDigit(Adafruit_ST7735 ptft,int digit,int x)
{
  Serial.print("-drawDigit-");
  Serial.print(digit);
  ptft.drawRGBBitmap(x,0,(*digitArr[digit]).pixels,da0.width,da0.height);
}


void setup(void) {
  Serial.begin(115200);
  Serial.print(F("Hello! ST77xx TFT Test"));

  // Use this initializer if using a 1.8" TFT screen:
  
  initScreens();
  
  // drawDigit(tft,1);
  // drawDigit(tft2,2);
  // drawDigit(tft3,3);
  // drawDigit(tft4,4);

  // tft. drawRGBBitmap(0,0,da0.pixels,da0.width,da0.height);
  // tft2.drawRGBBitmap(0,0,da1.pixels,da1.width,da1.height);
  // tft3.drawRGBBitmap(0,0,da2.pixels,da2.width,da2.height);
  // tft4.drawRGBBitmap(0,0,da3.pixels,da3.width,da3.height);

  tft.setTextSize(1);
  printBoth("Connect to Wifi.");
  connectWifi();
  configTime(8*3600,0,NTP1,NTP2,NTP3);
  delay(1000);
  
  // myTimer = timerBegin(0,80000,true);
  // timerAttachInterrupt(myTimer,&onTimer,true);
  // timerAlarmWrite(myTimer,10000,true);
  // timerAlarmEnable(myTimer);
  // OR use this initializer if using a 1.8" TFT screen with offset such as WaveShare:
  // tft.initR(INITR_GREENTAB);      // Init ST7735S chip, green tab

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  //tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

  // OR use this initializer (uncomment) if using a 0.96" 160x80 TFT:
  //tft.initR(INITR_MINI160x80);  // Init ST7735S mini display
  // OR use this initializer (uncomment) if using a 0.96" 160x80 TFT with 
  // plug-in FPC (if you see the display is inverted!)
  //tft.initR(INITR_MINI160x80_PLUGIN);  // Init ST7735S mini display

  // OR use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT:
  //tft.init(240, 240);           // Init ST7789 240x240

  // OR use this initializer (uncomment) if using a 1.69" 280x240 TFT:
  //tft.init(240, 280);           // Init ST7789 280x240

  // OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
  //tft.init(240, 320);           // Init ST7789 320x240

  // OR use this initializer (uncomment) if using a 1.14" 240x135 TFT:
  //tft.init(135, 240);           // Init ST7789 240x135
  
  // OR use this initializer (uncomment) if using a 1.47" 172x320 TFT:
  //tft.init(172, 320);           // Init ST7789 172x320

  // SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
  // Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
  // may end up with a black screen some times, or all the time.
  //tft.setSPISpeed(40000000);

  printBoth("Initialized");
  u8g2.begin(tft);
  u8g2_2.begin(tft2);
  u8g2_3.begin(tft3);
  printBoth("started u8g2,about to set chinese font..");
  //u8g2.enableUTF8Print();
  //u8g2.setFont(u8g2_font_unifont_t_chinese1);
  
  u8g2.setFont(u8g2_font_wqy16_t_gb2312a);
  u8g2_2.setFont(u8g2_font_wqy16_t_gb2312a);
  u8g2_3.setFont(u8g2_font_wqy16_t_gb2312a);

  //u8g2.setFont(u8g2_font_wqy16_t_chinese3);
  //u8g2_2.setFont(u8g2_font_wqy16_t_chinese3);

  //u8g2.setFontMode(1);                 // use u8g2 transparent mode (this is default)
  //u8g2.setFontDirection(0);            // left to right (this is default)
  u8g2.setForegroundColor(ST77XX_WHITE);      // apply Adafruit GFX color
  u8g2_2.setForegroundColor(ST77XX_BLUE);      // apply Adafruit GFX color
  u8g2_3.setForegroundColor(ST77XX_BLUE);      // apply Adafruit GFX color

  u8g2.setCursor(10,80);  
  u8g2.println("正在获取时间");

  
  
  timeinfo_last.tm_hour=-1;
  timeinfo_last.tm_min=-1;


  struct tm timeinfo;
  while(!getLocalTime(&timeinfo, 1000))
  {
    delay(1000); 
    printBoth(".");   
  }
  Serial.println("已获取时间。");

  //u8g2_2.setCursor(0,80);  
  //u8g2_2.println("正在获取时间");
  //tft.setFont(&FreeSans24pt7b);
  //tft2.setFont(&FreeSans24pt7b);
  //tft3.setFont(&FreeSans24pt7b);
  //tft4.setFont(&FreeSans24pt7b);
}

void printBoth(const char* str)
{
  Serial.print(str);
  tft.print(str);
}

void connectWifi()
{
  int ic=0;
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

while (WiFi.status() != WL_CONNECTED)
{
  printBoth("Connect to Wifi:");
  printBoth(ssid);
  ic=0;
  WiFi.begin(ssid, password);
  delay(1000);
  while (WiFi.status() != WL_CONNECTED && ic<20) {  
    printBoth("-");
    delay(1000);
    ic++;
  }
  
  if(WiFi.status() != WL_CONNECTED)
  {
  ic=0;

  printBoth("Change to Wifi:");
  printBoth(ssid1);

  WiFi.begin(ssid1, password1);
  delay(1000);
  while (WiFi.status() != WL_CONNECTED && ic<10) {  
    printBoth("-");
    delay(1000);
    ic++;
  }
  }
}

  //u8g2.setCursor(_x(0),_y(0));
  printBoth("WiFi connected!");

//------------Wifi Manager-----------------//
//   WiFiManager wm;
//   tft.println("Trying to connect to WiFi...");
//   tft.setFont(&FreeSansBold24pt7b);
//  bool response = wm.autoConnect(ssid, password);
//   if (!response) {
//     Serial.println("Failed to connect. Retrying connection ...");
//     //Try again in 5s.
//     ESP.restart();
//     delay(3000);
//   } 
//   else 
//   {
//     Serial.println("Connected to wifi with IP: ");
//     String ip = WiFi.localIP().toString();
//     Serial.println(WiFi.localIP());
//   }
}

int ic=0;
int firstShow=0;
void loop(){
  if(ic%120==0)
  {
    getWeather();
  }
  printLocalTime();
  //ic=(ic+1)%600;
  ic=(ic+1)%3000;
  delay(1000);

  if(ic%2==0)
  {
    u8g2_2.setCursor(dotx,120);
    u8g2_2.print("■");
    u8g2_2.setCursor(dotx,60);
    u8g2_2.print("■");

    // u8g2_3.setCursor(-7,120);
    // u8g2_3.print("■");
    // u8g2_3.setCursor(-7,60);
    // u8g2_3.print("■");
  }
  else
  {
    //清屏两点部分
    tft2.fillRect(dotx,40,10,100,ST77XX_BLACK);
    // tft3.fillRect(0,40,10,100,ST77XX_BLACK);
  }
}

void clearScreens()
{
  tft.fillScreen(ST77XX_BLACK);
  tft2.fillScreen(ST77XX_BLACK);
  tft3.fillScreen(ST77XX_BLACK);
  tft4.fillScreen(ST77XX_BLACK);
}

void initScreens()
{
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  tft.fillScreen(ST77XX_BLACK);
  tft2.initR(INITR_BLACKTAB);
  tft2.fillScreen(ST77XX_BLACK);
  tft3.initR(INITR_BLACKTAB);
  tft3.fillScreen(ST77XX_BLACK);
  tft4.initR(INITR_BLACKTAB);
  tft4.fillScreen(ST77XX_BLACK);
}



void printLocalTime() {
  


  time_t now;
  now=time(NULL);
  //if (getLocalTime(&timeinfo, 1000)) { // 5000ms超时时间
  struct tm * ltm=localtime(&now);

  {
    // 成功获取时间，格式化并打印
    if(firstShow==0)
    {
      firstShow++;
      tft.fillScreen(ST77XX_BLACK);
    }
    //String currentTime = String(asctime(&timeinfo));
    String currentTime = String(asctime(ltm));
    currentTime.trim(); // 移除字符串尾部的换行符
    

    printDigitHour(ltm->tm_hour,timeinfo_last.tm_hour,timeinfo_last.tm_hour==0 ||ltm->tm_sec==0);
    printDigitMin(ltm->tm_min,timeinfo_last.tm_min,timeinfo_last.tm_min==0 ||ltm->tm_sec==0);
    
    //printDigit(tft4,timeinfo.tm_mday,timeinfo_last.tm_mday,timeinfo_last.tm_mday==0 ||timeinfo.tm_sec==0);
    
    // tft3.fillRect(0,30,tft3.width(),90,ST77XX_BLACK);
    // tft3.setCursor(0,80);
    // tft3.setTextColor(ST77XX_BLUE);
    // tft3.setTextSize(1);
    // tft3.println(to2Ch(timeinfo.tm_sec));

    // tft4.setTextSize(1);
    // tft4.setCursor(0,80);
    // tft4.setTextColor(ST77XX_RED);
    // tft4.println(timeinfo.tm_year+1900)+String("-");
    // String date = to2Ch(timeinfo.tm_mon) + String("-") + to2Ch(timeinfo.tm_mday);
    // tft4.println(date);

    
    timeinfo_last.tm_hour = ltm->tm_hour;
    timeinfo_last.tm_min = ltm->tm_min;
  
  }
}

//转成2个字符长度的String
String to2Ch(int v)
{
  String s=String(v);
  if(v<10)
    s="0"+s;
  return s;
}


void printDigitHour(int h,int lasth,bool clearScr)
{
  // if(clearScr || h!=lasth)
  // {
  //   tft.fillScreen(ST77XX_BLACK);
  //   tft2.fillScreen(ST77XX_BLACK);
  // }

  
  int h1 = (h>12?h-12:h)/10;
  int h2 = (h>12?h-12:h)%10;
  // Serial.print("lasth:");
  // Serial.println(lasth);
  // Serial.print("h:");
  // Serial.println(h);

  if(lasth!=h)
  {
    // if(h1==0)
    // {
    //   tft.fillScreen(ST77XX_BLACK);
    // }
    // else
    // {
    //   drawDigit(tft,h1,16);
    // }
    drawDigit(tft2,h2,0);
  }
    
  u8g2.setCursor(0,50);
  //tft.setCursor(10,50);
  u8g2.println("北京天气:");
  u8g2.println(Weather_date);
  //u8g2.println(Weather_desc);
  u8g2.println( Weather_desc_day + "-" +  Weather_desc_night);
  u8g2.println(Weather_temp+" ("+ Weather_temp_day + "-" + Weather_temp_night +")");
  u8g2.println(Weather_wind);
  
  
  // ptft.setCursor(0,80);
  // String s=String(h);
  // if(h<10)
  //   s="0"+s;

  // ptft.setTextSize(2);
  // ptft.print(s);
}

void printDigitMin(int v,int lastv,bool clearScr)
{
  // if(clearScr || v!=lastv)
  // {
  //   tft3.fillScreen(ST77XX_BLACK);
  //   tft4.fillScreen(ST77XX_BLACK);
  // }
if(v!=lastv)
{
  int v1 = v/10;
  int v2 = v%10;
  drawDigit(tft3,v1,16);
  drawDigit(tft4,v2,0);
}
}

void getWeather()
{
 
      String wea = getWeatherReq("base");
      if(wea.length()>0)
      {
        StaticJsonDocument<300> doc;
        deserializeJson(doc,wea);
      
        Weather_desc=String((const char *)doc["lives"][0]["weather"]);
        Weather_temp=String((const char *)doc["lives"][0]["temperature"]);
        Weather_wind=String((const char *)doc["lives"][0]["winddirection"])+String((const char *)doc["lives"][0]["windpower"]);
        Weather_reportdate=String((const char *)doc["lives"][0]["reporttime"]).substring(0,10);
      }
      
      if(Weather_date!=Weather_reportdate)
      {
        wea = getWeatherReq("all");
        if(wea.length()>0)
        {
          StaticJsonDocument<1500> doc;
          deserializeJson(doc,wea);
          Serial.println(wea);
          Weather_date=String((const char *)doc["forecasts"][0]["casts"][0]["date"]);
          Weather_desc_day=String((const char *)doc["forecasts"][0]["casts"][0]["dayweather"]);
          Weather_desc_night=String((const char *)doc["forecasts"][0]["casts"][0]["nightweather"]);
          Weather_temp_day=String((const char *)doc["forecasts"][0]["casts"][0]["daytemp"]);
          Weather_temp_night=String((const char *)doc["forecasts"][0]["casts"][0]["nighttemp"]);
        }
      }
  
}

String getWeatherReq(String base)
{
  String result="";
  Serial.println("Getting weather ...");
  String url = "https://restapi.amap.com/v3/weather/weatherInfo?parameters&key=e094cccaa9f94c734344ab015d8b4ec6&city=110000&extensions="+base+"&output=JSON";
  HTTPClient http;
  http.begin(url);
  int httpCode=http.GET();
  if(httpCode>0)
    result = http.getString();
  Serial.println(result);
  return result;
}
// void getHttpTime()
// {
//     String url = "https://quan.suning.com/getSysTime.do";
//     HTTPClient http;
//     http.begin(url);
//     int httpCode=http.GET();
//     if(httpCode>0)
//     {
//         String time = http.getString();

//     }
//     else
//       return "";
// }

// void loop() {
  
//   uint16_t time = millis();
//   tft.fillScreen(ST77XX_BLACK);
//   tft2.fillScreen(ST77XX_BLACK);
//   tft3.fillScreen(ST77XX_BLACK);
//   tft4.fillScreen(ST77XX_BLACK);
//   time = millis() - time;

//   Serial.println(time, DEC);
//   delay(500);

//   Serial.println("Large block text");
//   // large block of text
//   tft.fillScreen(ST77XX_BLACK);
//   //testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
//   testdrawtext(tft,"First Screen",ST77XX_WHITE);

//   tft2.fillScreen(ST77XX_BLACK);
//   //testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
//   testdrawtext(tft2,"2222 The Second Screen",ST77XX_WHITE);

//   tft3.fillScreen(ST77XX_BLACK);
//   //testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
//   testdrawtext(tft3,"3333 The Third Screen",ST77XX_WHITE);

//   tft4.fillScreen(ST77XX_BLACK);
//   //testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
//   testdrawtext(tft4,"4444 The Forth Screen",ST77XX_WHITE);

//   delay(3000);



// Serial.println("TFT print");
//   // tft print function!
//   tftPrintTest(tft);
//   tftPrintTest(tft2);
//   tftPrintTest(tft3);
//   tftPrintTest(tft4);
//   delay(4000);

// // Serial.println("Single pixel");
// //   // a single pixel
// //   tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN);
// //   delay(500);

// Serial.println("Draw line");
//   // line draw test
//   testlines(tft,ST77XX_YELLOW);
//   testlines(tft2,ST77XX_YELLOW);
//   testlines(tft3,ST77XX_YELLOW);
//   testlines(tft4,ST77XX_YELLOW);
//   delay(3000);

// Serial.println("Optimized lines");
//   // optimized lines
//   testfastlines(tft,ST77XX_RED, ST77XX_BLUE);
//   testfastlines(tft2,ST77XX_RED, ST77XX_BLUE);
//   testfastlines(tft3,ST77XX_RED, ST77XX_BLUE);
//   testfastlines(tft4,ST77XX_RED, ST77XX_BLUE);
//   delay(3000);

// Serial.println("Rects");
//   testdrawrects(tft,ST77XX_GREEN);
//   testdrawrects(tft2,ST77XX_GREEN);
//   testdrawrects(tft3,ST77XX_GREEN);
//   testdrawrects(tft4,ST77XX_GREEN);
//   delay(500);

// Serial.println("Fill rects");
//   testfillrects(tft,ST77XX_YELLOW, ST77XX_MAGENTA);
//   testfillrects(tft2,ST77XX_YELLOW, ST77XX_MAGENTA);
//   testfillrects(tft3,ST77XX_YELLOW, ST77XX_MAGENTA);
//   testfillrects(tft4,ST77XX_YELLOW, ST77XX_MAGENTA);
//   delay(500);

// Serial.println("Fill screen");
//   tft.fillScreen(ST77XX_BLACK);
//   tft2.fillScreen(ST77XX_BLACK);
//   tft3.fillScreen(ST77XX_BLACK);
//   tft4.fillScreen(ST77XX_BLACK);

//   testfillcircles(tft,10, ST77XX_BLUE);
//   testdrawcircles(tft,10, ST77XX_WHITE);

//   testfillcircles(tft2,10, ST77XX_BLUE);
//   testdrawcircles(tft2,10, ST77XX_WHITE);

//   testfillcircles(tft3,10, ST77XX_BLUE);
//   testdrawcircles(tft3,10, ST77XX_WHITE);

//   testfillcircles(tft4,10, ST77XX_BLUE);
//   testdrawcircles(tft4,10, ST77XX_WHITE);
//   delay(500);

// Serial.println("Round rects");
//   testroundrects(tft);
//   testroundrects(tft2);
//   testroundrects(tft3);
//   testroundrects(tft4);
//   delay(500);

// Serial.println("Triangles");
//   testtriangles(tft);
//   testtriangles(tft2);
//   testtriangles(tft3);
//   testtriangles(tft4);
//   delay(500);

// Serial.println("Buttons");
//   mediabuttons();
//   delay(500);

//   Serial.println("done");
//   delay(1000);
// }